package com.cat.conf;


import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.cat.conf.mvc.CatHandlerExceptionResolver;
import com.cat.conf.mvc.CompositeFilter;
import com.cat.conf.mvc.ReqRspAspect;
import com.google.common.base.Charsets;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import javax.annotation.Resource;
import javax.servlet.DispatcherType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 用户Mvc配置中心
 *
 * @author
 * @create 2018-07-25 17:51
 **/
// @Configuration
// @ConditionalOnWebApplication
public class MvcConfiguration extends WebMvcConfigurerAdapter {

    // @Resource
    // private MvcProperties mvcProperties;

    /**
     * 加入异常链
     *
     * @param exceptionResolvers
     * @date 2018-03-01 17:40:32
     * @since v1.0.0
     */
    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
        CatHandlerExceptionResolver resolver = new CatHandlerExceptionResolver();
            exceptionResolvers.add(resolver);
    }


    /**
     * controller拦截
     *
     * @return
     * @date 2018-03-01 17:39:53
     * @since v1.0.0
     */
    @Bean
    public ReqRspAspect reqRspAspect() {
        return new ReqRspAspect();
    }

    /**
     * filter过滤链
     *
     * @return
     * @date 2018-03-01 17:40:03
     * @since v1.0.0
     */
    @Bean
    public CompositeFilter compositeFilter() {
        CompositeFilter compositeFilter = new CompositeFilter();
        compositeFilter.setFilters(Arrays.asList(new CharacterEncodingFilter()));
        // compositeFilter.setFilters(Arrays.asList(new CharacterEncodingFilter(), logMDCFilter()));
        return compositeFilter;
    }



    /**
     * filter注册
     *
     * @return
     * @date 2018-03-01 18:00:42
     * @since v1.0.0
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        DelegatingFilterProxy filterProxy = new DelegatingFilterProxy("compositeFilter");
        filterProxy.setTargetFilterLifecycle(true);
        filterRegistration.setFilter(filterProxy);
        filterRegistration.setEnabled(true);
        filterRegistration.addUrlPatterns("/*");
        filterRegistration.setDispatcherTypes(DispatcherType.REQUEST);
        return filterRegistration;
    }
    /**
     * 自定义转换器
     *
     * @param converters
     * @date 2018-03-08 16:50:51
     * @since v1.0.0
     */
    // @Override
    // public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    //     // xml text
    //     StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
    //     List<MediaType> StringMediaTypes = new ArrayList<>();
    //     StringMediaTypes.add(MediaType.TEXT_PLAIN);
    //     StringMediaTypes.add(MediaType.TEXT_XML);
    //     stringConverter.setSupportedMediaTypes(StringMediaTypes);
    //     converters.add(0, stringConverter);
    //
    //     // 1. 定义一个convert 转换消息的对象
    //     FastJsonHttpMessageConverter jsonConverter = new FastJsonHttpMessageConverter();
    //     // 2.添加fastjson 的配置信息 比如 是否要格式化 返回的json数据
    //     FastJsonConfig fastJsonConfig = new FastJsonConfig();
    //     fastJsonConfig.setCharset(Charsets.UTF_8);
    //     fastJsonConfig.setFeatures(Feature.IgnoreNotMatch);
    //     fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
    //     fastJsonConfig.setSerializerFeatures(
    //             // 格式化
    //             // SerializerFeature.PrettyFormat,
    //             // key 值加引号
    //             SerializerFeature.QuoteFieldNames,
    //             // 空值处理
    //             SerializerFeature.WriteNullStringAsEmpty,
    //             SerializerFeature.WriteNullNumberAsZero,
    //             SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty,
    //             // 处理循环引用
    //             SerializerFeature.DisableCircularReferenceDetect,
    //             // 格式化日期
    //             SerializerFeature.WriteDateUseDateFormat);
    //
    //     // V1.0.3开始Long 不再转String
    //     // SerializeConfig serializeConfig = SerializeConfig.globalInstance;
    //     // serializeConfig.put(Long.class, ToStringSerializer.instance);
    //     // fastJsonConfig.setSerializeConfig(serializeConfig);
    //
    //     jsonConverter.setFastJsonConfig(fastJsonConfig);
    //     // json
    //     List<MediaType> jsonMediaTypes = new ArrayList<>();
    //     jsonMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
    //     jsonConverter.setSupportedMediaTypes(jsonMediaTypes);
    //     converters.add(1, jsonConverter);
    //
    //     super.configureMessageConverters(converters);
    // }

    // @Bean
    // public LogMDCFilter logMDCFilter() {
    //     return new LogMDCFilter();
    // }


    // @Bean
    // public JawsExcelView jawsExcelView() {
    //     return new JawsExcelView();
    // }
    //
    // @Bean
    // public JawsViewResolver jawsViewResolver() {
    //     return new JawsViewResolver();
    // }

    // /**
    //  * 视图配置
    //  */
    // @Override
    // public void configureViewResolvers(ViewResolverRegistry registry) {
    //     super.configureViewResolvers(registry);
    //     registry.viewResolver(jawsViewResolver());
    // }



    /**
     * interceptor
     *
     * @param registry ''
     * @date 2018-03-01 17:40:18
     * @since v1.0.0
     */
    // @Override
    // public void addInterceptors(InterceptorRegistry registry) {
    // registry.addInterceptor(new TestInterceptor()).addPathPatterns("/**");
    // }

    // @Configuration
    // @Profile("dev")
    // @EnableSwagger2
    // protected class JawsSwaggerConfiguration extends WebMvcConfigurerAdapter {
    //
    //     @Override
    //     public void addResourceHandlers(ResourceHandlerRegistry registry) {
    //         registry.addResourceHandler(new String[]{"swagger-ui.html"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/"});
    //         registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"});
    //     }
    //
    //     @Bean
    //     public Docket createRestApi(MvcProperties mvcProperties) {
    //         return (new Docket(DocumentationType.SWAGGER_2)).apiInfo(this.apiInfo(mvcProperties)).select().apis(RequestHandlerSelectors.basePackage(mvcProperties.getSwaggerBasepackage()))
    //                 .paths(PathSelectors.any()).build();
    //     }
    //
    //     private ApiInfo apiInfo(MvcProperties mvcProperties) {
    //         return (new ApiInfoBuilder()).title(mvcProperties.getSwaggerServiceName() + " Restful APIs").description(mvcProperties.getSwaggerServiceDescription())
    //                 .contact(mvcProperties.getSwaggerServiceName()).version(mvcProperties.getSwaggerServiceVersion()).build();
    //     }
    // }

    // @Configuration
    // @ConditionalOnClass({FeignClient.class, Decoder.class})
    // protected class FeignConfig {
    //
    //     @Bean
    //     public JawsFeignInterceptor jawsFeignInterceptor() {
    //         return new JawsFeignInterceptor();
    //     }
    //
    //     @Bean
    //     @Profile("dev")
    //     @ConditionalOnProperty(prefix = "yjs.jaws", name = "mock", havingValue = "true", matchIfMissing = false)
    //     public Client jawsFeignClient(CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory) {
    //         return new JawsFeignClient(new Client.Default(null, null), cachingFactory, clientFactory);
    //     }
    //
    //     @Bean
    //     public FeignClientEndpoint feignClientEndpoint() {
    //         return new FeignClientEndpoint();
    //     }
    //
    //     @Bean
    //     public Decoder feignDecoder() {
    //         return new ResponseEntityDecoder(new SpringDecoder(feignHttpMessageConverter()));
    //     }
    //
    //     public ObjectFactory<HttpMessageConverters> feignHttpMessageConverter() {
    //         // 定义一个convert 转换消息的对象
    //         FastJsonHttpMessageConverter jsonConverter = new FastJsonHttpMessageConverter();
    //         // 2 添加fastjson 的配置信息 比如 是否要格式化 返回的json数据
    //         FastJsonConfig fastJsonConfig = new FastJsonConfig();
    //         fastJsonConfig.setCharset(Charsets.UTF_8);
    //         fastJsonConfig.setFeatures(Feature.IgnoreNotMatch);
    //         fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
    //
    //         fastJsonConfig.setSerializerFeatures(
    //                 // 格式化
    //                 // SerializerFeature.PrettyFormat,
    //                 // key 值加引号
    //                 SerializerFeature.QuoteFieldNames,
    //                 // 空值处理
    //                 SerializerFeature.WriteNullStringAsEmpty,
    //                 SerializerFeature.WriteNullNumberAsZero,
    //                 SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty,
    //                 // 处理循环引用
    //                 SerializerFeature.DisableCircularReferenceDetect,
    //                 // 格式化日期
    //                 SerializerFeature.WriteDateUseDateFormat);
    //
    //         jsonConverter.setFastJsonConfig(fastJsonConfig);
    //         // json
    //         List<MediaType> jsonMediaTypes = new ArrayList<>();
    //         jsonMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
    //         jsonConverter.setSupportedMediaTypes(jsonMediaTypes);
    //         HttpMessageConverters httpMessageConverters = new HttpMessageConverters(jsonConverter);
    //         return new ObjectFactory<HttpMessageConverters>() {
    //             @Override
    //             public HttpMessageConverters getObject() throws BeansException {
    //                 return httpMessageConverters;
    //             }
    //         };
    //     }
    // }
}
